package com.gardeneaters.game_v0.rules;

import com.gardeneaters.game_v0.playingfield.Hexagon;

// this class is extended by Power and Head classes;
public class Hexagons {

	protected Hexagon [][] hexagons;
	protected int NumOfHexX,NumOfHexY;
	
	protected Hexagons(Hexagon[][] _hexagons) {
		this.hexagons = _hexagons;
		NumOfHexY = _hexagons.length;
		NumOfHexX = _hexagons[0].length;
	}
	
	protected boolean isInLoop(int i, int j) {
		boolean isInLoop = false;
		
		Hexagon tempHex;
		int pointingTo;
		int[] nextPos = new int[2];
		int team = hexagons[i][j].getTeam();
		nextPos[0]=i;
		nextPos[1]=j;
		do{
			hexagons[nextPos[0]][nextPos[1]].calculating=true;
			pointingTo = hexagons[nextPos[0]][nextPos[1]].getPointingTo();
			tempHex = getHexagon(pointingTo,nextPos[0], nextPos[1]);
			if(tempHex==null)// accommodates pointingTo==0 condition and also edge of grid.
			{
			//	System.out.println("yoo"+i+" "+j);
				nextPos[0]=-1;
				nextPos[1]=-1;
				break;
			}
			else if(tempHex.getTeam()!= team)// when team changes
			{
			//	System.out.println("yo"+i+" "+j+" team "+hexagons[i][j].getTeam()+" "+team);
			//	System.out.println("nextPos "+nextPos[0]+" "+nextPos[1]);
			//	nextPos = getHexagonPos(pointingTo,nextPos[0], nextPos[1]);
			//	System.out.println("nextPos2 "+nextPos[0]+" "+nextPos[1]+" team "+tempHex.getTeam()+" "+hexagons[nextPos[0]][nextPos[1]].getTeam());
				nextPos[0]=-1;
				nextPos[1]=-1;
				break;
			}
			nextPos = getHexagonPos(pointingTo,nextPos[0], nextPos[1]);
		}while(!hexagons[nextPos[0]][nextPos[1]].calculating);
		
		if(nextPos[0]==i && nextPos[1]==j)
			isInLoop = true;
		
		nextPos[0]=i;
		nextPos[1]=j;
		do{
			hexagons[nextPos[0]][nextPos[1]].calculating=false;
			pointingTo = hexagons[nextPos[0]][nextPos[1]].getPointingTo();
			tempHex = getHexagon(pointingTo, nextPos[0], nextPos[1]);
			if(tempHex==null)// accommodates pointingTo==0 condition and also edge of grid.
				break;
			else if(tempHex.getTeam()!= hexagons[i][j].getTeam())// when team changes
				break;
			nextPos = getHexagonPos(pointingTo,nextPos[0], nextPos[1]);
		}while(hexagons[nextPos[0]][nextPos[1]].calculating);
		
		return isInLoop;
	}
	
	protected boolean isPointingAtMe(int i, int j){
		
		for(int k =1; k<7; k++)
		{
			if(isPointingAtMe(k,i,j) )// calls overloaded method
			{
				return true;
			}
		}
		
		return false;
		
	}
	
	protected boolean isPointingAtMe(int side, int i, int j){
		if(side ==0 )
			return false;
		Hexagon tempHex=null;
		try{
		tempHex = getHexagon(side, i, j);
		}catch(Exception e){
			tempHex=null;
			return false;
		}
		if(tempHex==null)
			return false;
		
		int pointingTo = tempHex.getPointingTo();
		if(side == getHexOppositeSide(pointingTo))
			return true;
//		if((pointingTo==1 && side==4) || (pointingTo==4 && side==1))
//			return true;
//		else if((pointingTo==2 && side ==5) || (pointingTo==5 && side ==2))
//			return true;
//		else if((pointingTo==3 && side ==6) || (pointingTo==6 && side ==3))
//			return true;
		
		return false;
	}
	
	protected boolean isUnderAttack(int i, int j){
		
		int team = hexagons[i][j].getTeam();
		Hexagon tempHex;
		for(int k =1; k<7; k++)
		{
			if(isPointingAtMe(k,i,j) )// calls overloaded method
			{
				tempHex = getHexagon(k, i, j);
				if(tempHex.getTeam()!=team)
					return true;
			}
		}
		return false;
	}
	
	protected Hexagon getHexagon(int side, int i, int j)
	{//i,j is actually hexagon[i][j]
		Hexagon tempHex = null;
		int [] tempPos = getHexagonPos(side,i,j);
		if(tempPos==null)
			tempHex = null;
		else
			try{
				tempHex = hexagons[tempPos[0]][tempPos[1]];
			}
			catch(ArrayIndexOutOfBoundsException e){
				return null;
			}
		return tempHex;
	}
	
	protected int[] getHexagonPos(int side, int i, int j)
	{//'side' is side of hexagon. Method returns position of hexagon at side of current hexagon[i][j]
		int [] tempPos = null;
		switch (side)
		{
			case 1:
			{
				if(i>0)
				{
					if(i%2==0)
					{
						tempPos = new int[2];
						tempPos[0]=i-1;
						tempPos[1]=j;
					}
					else if((j+1)<NumOfHexX)
					{
						tempPos = new int[2];
						tempPos[0]=i-1;
						tempPos[1]=j+1;
					}
				}
				break;
			}
			case 2:
			{
				if((j+1)<NumOfHexX)
				{
					tempPos = new int[2];
					tempPos[0]=i;
					tempPos[1]=j+1;
				}
				break;
			}
			case 3:
			{
				if((i+1)<NumOfHexY)
				{
					if(i%2==0)
					{
						tempPos = new int[2];
						tempPos[0]=i+1;
						tempPos[1]=j;
					}
					else if((j+1)<NumOfHexX)
					{
						tempPos = new int[2];
						tempPos[0]=i+1;
						tempPos[1]=j+1;
					}
				}
				break;
			}
			case 4:
			{
				if((i+1)<NumOfHexX)
				{
					if(i%2!=0)
					{
						tempPos = new int[2];
						tempPos[0]=i+1;
						tempPos[1]=j;
					}
					else if(j>0)
					{
						tempPos = new int[2];
						tempPos[0]=i+1;
						tempPos[1]=j-1;
					}
				}
				break;
			}
			case 5:
			{
				if(j>0)
				{
					tempPos = new int[2];
					tempPos[0]=i;
					tempPos[1]=j-1;
				}
				break;
			}
			case 6:
			{
				if(i>0)
				{
					if(i%2!=0)
					{
						tempPos = new int[2];
						tempPos[0]=i-1;
						tempPos[1]=j;
					}
					else if(j>0)
					{
						tempPos = new int[2];
						tempPos[0]=i-1;
						tempPos[1]=j-1;
					}
				}
				break;	
			}
			default:
			{
				tempPos=null;
			}
		}
		return tempPos;
	}
	
	protected int getHexOppositeSide(int side){
		
		switch (side){
		case 1:
			return 4;
		case 2:
			return 5;
		case 3:
			return 6;
		case 4:
			return 1;
		case 5:
			return 2;
		case 6:
			return 3;
		default:
			return 0;
		
		}
	}
	

}
